package scenic.study.basic_knowledge.collections;

import org.apache.log4j.Logger;
import org.junit.Test;
import scenic.MyLogger;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

/**
 * Created by scenic on 16/6/12.
 */
public class TestHashTableAndMap {

    Logger logger = MyLogger.get(TestHashTableAndMap.class);

    class EntityForHashTableKey {

        private final int name;

        EntityForHashTableKey(int name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "key: " + name;
        }

        @Override
        public boolean equals(Object obj) {
            System.out.println("call the key equals param obj " + obj + " this obj " + this);
            if (obj instanceof EntityForHashTableKey) {
                return this.name == ((EntityForHashTableKey) obj).name;
            }
            return super.equals(obj);
        }

        @Override
        public int hashCode() {
//            int code = name;
            int code = 30000;
            System.out.println("call key hashCode " + code);
            return code;
        }
    }

    class EntityForHashTableValue {

        private final int name;

        EntityForHashTableValue(int name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "value:" + name;
        }


        @Override
        public boolean equals(Object obj) {
            System.out.println("call the value equals param obj " + obj + " this obj " + this);

            return super.equals(obj);
        }

        @Override
        public int hashCode() {
            int code = super.hashCode();
            System.out.println("call value hashCode " + code);
            return code;
        }
    }


    @Test
    public void testHashList() {
        HashSet hashSet = new HashSet();
//        List hashSet = new ArrayList<>();

        System.out.println("begin HashSet add=============");
        hashSet.add(new EntityForHashTableKey(1));
        hashSet.add(new EntityForHashTableKey(2));
        hashSet.add(new EntityForHashTableKey(3));
        hashSet.add(new EntityForHashTableKey(3));


        System.out.println("collection size is " + hashSet.size());

        System.out.println("begin HashSet remove============= \n");
        System.out.println("get value " + hashSet.remove(new EntityForHashTableKey(2)));
    }

    @Test
    public void testHashTable() {


        Hashtable hashtable = new Hashtable();
        System.out.println("begin put=============");
        hashtable.put(new EntityForHashTableKey(1), new EntityForHashTableValue(1));
        hashtable.put(new EntityForHashTableKey(2), new EntityForHashTableValue(1));
        hashtable.put(new EntityForHashTableKey(3), new EntityForHashTableValue(1));
        hashtable.put(new EntityForHashTableKey(3), new EntityForHashTableValue(1));
        hashtable.put(new EntityForHashTableKey(3), new EntityForHashTableValue(1));
        hashtable.put(new EntityForHashTableKey(3), new EntityForHashTableValue(1));
        hashtable.put(new EntityForHashTableKey(3), new EntityForHashTableValue(1));


        System.out.println("begin get=============\n");
        System.out.println("get value " + hashtable.get(new EntityForHashTableKey(3)));
    }



    private Map fillMapOrTable( Map map) {
        map.put("1+1", 2d);
        map.put("(2 - 1)", 1d);
        map.put("2*3/(2 - 1)+3*(4 - 1)", 15d);

        map.put("-1 - 2 - 3", -6d);
        map.put("1 + 2 - 3", 0d);
        map.put("(1+2) * 3", 9d);
        map.put("-1 - (-2)", 1d);

        map.put("sin(1+2)", Math.sin(1 + 2));
        map.put("sin(sin(1 + 2))", Math.sin(Math.sin(1 + 2)));
        map.put("sin((1+2) * 3)", Math.sin(9));
        map.put("sqrt((1+2) * 3)", Math.sqrt(9));
        map.put("sqrt(9) - 6", Math.sqrt(9) - 6);
        map.put("3 + 2 % 5", 3.0 + 2 % 5);

        return map;

    }

    @Test
    public void testMapOrder(){

        fillMapOrTable(new HashMap<>()).forEach((integer, s) -> logger.debug(integer + "  \t\t\t\t " + s));
        System.out.println();
        fillMapOrTable(new LinkedHashMap()).forEach((integer, s) -> logger.debug(integer + "  \t\t\t\t " + s));



    }
}
